//
//  ViewController.swift
//  CoreImage动态模糊
//
//  Created by quanhao huang on 2019/12/26.
//  Copyright © 2019 quanhao huang. All rights reserved.
//

/*
 注意点
     1.imageView2.image?.ciImage 也许为nil 因为image不一定是基于CIImage下创建的。这种情况下image.ciImage = nil
 正确应该let ciImage = CIImage(image: imageView2.image!)
     2.CIContext的重用是很有必要的
 并且，CIContext和CIImage对象是不可变的，在线程之间共享这些对象是安全的。所以多个线程可以使用同一个GPU 或者 CPU CIContext 对象来渲染
 CIImage 对象。
 这意味着不应该使用 imageWithCIImage 来生成 UIImage，而应该自己创建维护 CIContext
     3.CPU / GPU
 Core Image 的另外一个优势，就是可以根据需求选择 CPU 或者 GPU 来处理。
 Context 创建的时候，我们可以给它设置为是基于 GPU 还是 CPU。
 基于 GPU 的话，处理速度更快，因为利用了 GPU 硬件的并行优势。可以使用 OpenGLES 或者 Metal 来渲染图像，这种方式CPU完全没有负担，应用程序的运行循环不会受到图像渲染的影响。
 但是 GPU 受限于硬件纹理尺寸，而且如果你的程序在后台继续处理和保存图片的话，那么需要使用 CPU，因为当 App 切换到后台状态时 GPU 处理会被打断。使用 CPU 渲染的 iOS 会采用 GCD 来对图像进行渲染，这保证了 CPU 渲染在大部分情况下更可靠，比 GPU 渲染更容易使用，可以在后台实现渲染过程。
 综上，对于复杂的图像滤镜使用 GPU 更好，但是如果在处理视频并保存文件，或保存照片到照片库中时，为避免程序进入后台对图片保存造成影响，这时应该使用 CPU 进行渲染。
 */

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var imageView1: UIImageView!
    @IBOutlet weak var imageView2: UIImageView!
    
    var context = CIContext(options: nil)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        imageView2.image = self.outputImageWithFilterName(filterName: "CIMotionBlur")
    }

    // CIMotionBlur
    func outputImageWithFilterName(filterName : String) -> UIImage {
        // 1. 将UIImage转换成CIImage
        let ciImage = CIImage(image: imageView2.image!)
        
        // 2. 创建滤镜
        let filter = CIFilter(name: filterName)
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue( 10, forKey: "inputRadius")
        // 3. 渲染并输出CIImage
        let outputImage = filter?.outputImage
        // 4. 获取绘制上下文
//        context = CIContext(options: nil)
        // 5. 创建输出CGImage
        let cgImage:CGImage = context.createCGImage(outputImage!, from: outputImage!.extent)!
        let image = UIImage.init(cgImage: cgImage)
        // 6. 返回image
        return image
    }

}

